// API配置
const API_BASE_URL = 'http://localhost:8000';

// 全局变量
let currentChatId = null;
let isDarkTheme = false; // 永远浅色主题
let currentMode = 'full'; // 'full' 或 'feature'
let selectedFile = null;
let isStreaming = false;
let streamController = null;
let isSidebarCollapsed = false;

// 新增全局变量保存 fileId
let uploadedFileId = null;

// 聊天历史数据
let chatHistory = {};
// 新增：为每个对话保存 loading 动画标志，并持久化
let chatLoadingFlags = {};

// 加载持久化的 loading 动画标志
function loadLoadingFlagsFromStorage() {
    try {
        const saved = localStorage.getItem('chatLoadingFlags');
        if (saved) {
            chatLoadingFlags = JSON.parse(saved);
        }
    } catch (e) {
        chatLoadingFlags = {};
    }
}

// 保存 loading 动画标志到 localStorage
function saveLoadingFlagsToStorage() {
    localStorage.setItem('chatLoadingFlags', JSON.stringify(chatLoadingFlags));
}

// DOM 元素
const chatMessages = document.getElementById('chatMessages');
const messageInput = document.getElementById('messageInput');
const sendBtn = document.getElementById('sendBtn');
const newChatBtn = document.querySelector('.new-chat-btn');
const themeToggle = document.getElementById('themeToggle');
const fileInput = document.getElementById('fileInput');
const uploadBtn = document.getElementById('uploadBtn');
const fileInfo = document.getElementById('fileInfo');
const fileName = document.getElementById('fileName');
const removeFile = document.getElementById('removeFile');
const modeButtons = document.querySelectorAll('.mode-btn');
const sidebar = document.getElementById('sidebar');
const sidebarToggle = document.getElementById('sidebarToggle');
const fileSize = document.getElementById('fileSize');
const uploadIcon = document.querySelector('.upload-icon');
const uploadLoading = document.querySelector('.upload-loading');
const chatList = document.getElementById('chatList');

// API调用函数
async function createConversation() {
    try {
        const response = await fetch(`${API_BASE_URL}/v1/conversation/createConversation`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            }
        });
        const data = await response.json();
        if (data.code === 10000) {
            // 兼容 data.data 为 {chatId: ...} 或 data.data 为字符串
            if (data.data && typeof data.data === 'object' && data.data.chatId) {
                return data.data.chatId;
            }
            if (typeof data.data === 'string') {
                return data.data;
            }
            return data.chatId || data.conversationId || (data.data && data.data.conversationId);
        } else {
            throw new Error(data.msg || '创建对话失败');
        }
    } catch (error) {
        console.error('创建对话失败:', error);
        throw error;
    }
}

async function getConversations() {
    try {
        const response = await fetch(`${API_BASE_URL}/v1/conversation/getConversations`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            }
        });
        
        const data = await response.json();
        
        if (data.code === 10000) {
            return data.data;
        } else {
            throw new Error(data.msg || '获取对话列表失败');
        }
    } catch (error) {
        console.error('获取对话列表失败:', error);
        throw error;
    }
}

async function getMessages(conversationId) {
    try {
        const response = await fetch(`${API_BASE_URL}/v1/conversation/getMessages?conversationId=${conversationId}`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            }
        });
        
        const data = await response.json();
        
        if (data.code === 10000) {
            return data.data;
        } else {
            throw new Error('获取消息失败');
        }
    } catch (error) {
        console.error('获取消息失败:', error);
        throw error;
    }
}

// 加载对话列表
async function loadConversations() {
    try {
        const data = await getConversations();
        
        // 清空现有列表
        chatList.innerHTML = '';
        
        if (data && data.chatList && data.chatList.length > 0) {
            // 只显示最近10条对话
            const recentChats = data.chatList.slice(0, 10);
            
            recentChats.forEach(chat => {
                const chatItem = document.createElement('div');
                chatItem.className = 'chat-item';
                chatItem.dataset.chatId = chat.chatId;
                chatItem.innerHTML = `
                    <i class="fas fa-comment"></i>
                    <span class="chat-title">${chat.chatTitle}</span>
                `;
                
                // 添加点击事件
                chatItem.addEventListener('click', function() {
                    selectChat(chat.chatId);
                    // 如果处于首次进入页面的悬浮状态，切换为正常聊天界面
                    const chatInputOuter = document.querySelector('.chat-input-outer');
                    const chatArea = document.querySelector('.chat-area');
                    const welcomeTip = document.getElementById('welcomeTip');
                    if (chatInputOuter && chatInputOuter.classList.contains('floating-input-only')) {
                        chatInputOuter.classList.remove('floating-input-only');
                    }
                    if (chatArea && chatArea.classList.contains('hide-chat-messages')) {
                        chatArea.classList.remove('hide-chat-messages');
                    }
                    if (welcomeTip) welcomeTip.style.display = 'none';
                });
                
                chatList.appendChild(chatItem);
                
                // 将对话信息存储到本地
                chatHistory[chat.chatId] = {
                    title: chat.chatTitle,
                    messages: []
                };
            });
            
            // 设置当前选中对话的高亮状态
            if (currentChatId) {
                document.querySelectorAll('.chat-item').forEach(item => {
                    item.classList.remove('active');
                    if (item.dataset.chatId === currentChatId) {
                        item.classList.add('active');
                    }
                });
            }
            // 不自动切换 currentChatId，不自动 selectChat
        }
    } catch (error) {
        console.error('加载对话列表失败:', error);
        showNotification('加载对话列表失败');
    }
}


// 初始化
document.addEventListener('DOMContentLoaded', function() {
    loadLoadingFlagsFromStorage(); // 恢复动画标志
    setupEventListeners();
    loadInitialData();
    initializeApp();
    
    // 检查是否是从编辑页面返回
    const url = new URL(window.location.href);
    const isFromEdit = url.searchParams.get('chatId');
    
    if (!isFromEdit) {
        // 只有首次进入页面时才显示悬浮状态
        const chatArea = document.querySelector('.chat-area');
        const chatInputOuter = document.querySelector('.chat-input-outer');
        const messageInput = document.getElementById('messageInput');
        const welcomeTip = document.getElementById('welcomeTip');

        // 首次进入页面，输入框悬浮，聊天消息区域隐藏，欢迎语显示
        chatInputOuter.classList.add('floating-input-only');
        chatArea.classList.add('hide-chat-messages');
        if (welcomeTip) welcomeTip.style.display = '';
    }
});

// 初始化应用
async function initializeApp() {
    try {
        // 检查URL参数中是否有chatId
        const url = new URL(window.location.href);
        const urlChatId = url.searchParams.get('chatId');
        
        // 如果有URL参数中的chatId，优先使用它
        if (urlChatId) {
            currentChatId = urlChatId;
            localStorage.setItem('currentChatId', urlChatId);
            // 从编辑页面返回时，确保显示正常的聊天界面
            const chatArea = document.querySelector('.chat-area');
            const chatInputOuter = document.querySelector('.chat-input-outer');
            const welcomeTip = document.getElementById('welcomeTip');
            chatInputOuter.classList.remove('floating-input-only');
            chatArea.classList.remove('hide-chat-messages');
            if (welcomeTip) welcomeTip.style.display = 'none';
        }
        // 只加载对话列表，不自动创建新对话
        await loadConversations();
        // 如果有当前对话，加载消息
        if (currentChatId) {
            await loadChatMessages(currentChatId);
        }
        // 不再自动添加欢迎消息
    } catch (error) {
        console.error('初始化应用失败:', error);
        showNotification('初始化失败，请检查网络连接');
    }
}

// 设置事件监听器
function setupEventListeners() {
    // 发送消息
    sendBtn.addEventListener('click', sendMessage);
    messageInput.addEventListener('keypress', function(e) {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            sendMessage();
        }
    });

    // 自动调整输入框高度
    messageInput.addEventListener('input', function() {
        this.style.height = 'auto';
        this.style.height = Math.min(this.scrollHeight, 120) + 'px';
    });

    // 聊天功能
    newChatBtn.addEventListener('click', function() {
        // 清空当前对话ID
        currentChatId = null;
        localStorage.removeItem('currentChatId');
        // 移除所有对话高亮
        document.querySelectorAll('.chat-item').forEach(item => item.classList.remove('active'));
        // 输入框动画回到首次进入状态
        const chatArea = document.querySelector('.chat-area');
        const chatInputOuter = document.querySelector('.chat-input-outer');
        const welcomeTip = document.getElementById('welcomeTip');
        chatInputOuter.classList.remove('to-bottom', 'to-middle', 'floating-input-only');
        // 触发动画
        chatInputOuter.classList.add('floating-input-only');
        setTimeout(() => {
            chatInputOuter.classList.add('to-middle');
            setTimeout(() => {
                chatInputOuter.classList.add('to-bottom');
            }, 400);
        }, 50);
        chatArea.classList.add('hide-chat-messages');
        if (welcomeTip) welcomeTip.style.display = '';
        // 清空输入框内容
        messageInput.value = '';
        messageInput.style.height = 'auto';
        // 新建对话后，确保发送按钮可用和图标为纸飞机
        sendBtn.disabled = false;
        sendBtn.classList.remove('stop', 'disabled');
        sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i>';
    });

    // 主题切换
    themeToggle.addEventListener('click', toggleTheme);

    // 侧边栏收起/展开
    sidebarToggle.addEventListener('click', toggleSidebar);

    // 文件上传
    uploadBtn.addEventListener('click', () => fileInput.click());
    fileInput.addEventListener('change', handleFileUpload);
    removeFile.addEventListener('click', removeUploadedFile);

    // 模式切换
    modeButtons.forEach(btn => {
        btn.addEventListener('click', function() {
            switchMode(this.dataset.mode);
        });
    });
}


// 切换侧边栏
function toggleSidebar() {
    isSidebarCollapsed = !isSidebarCollapsed;
    sidebar.classList.toggle('collapsed', isSidebarCollapsed);
    
    // 保存侧边栏状态
    localStorage.setItem('sidebarCollapsed', isSidebarCollapsed);
    
    // 显示提示
    const status = isSidebarCollapsed ? '收起' : '展开';
    showNotification(`侧边栏已${status}`);
}

// 发送消息
async function sendMessage() {
    let thisChatId = currentChatId; // 记录发送时的对话ID
    // 新增：首次无对话时先创建
    if (!currentChatId) {
        try {
            const newChatId = await createConversation();
            if (newChatId) {
                await loadConversations();
                await selectChat(newChatId); // 关键：切换到新对话
                currentChatId = newChatId;
                thisChatId = newChatId; // 关键：更新 thisChatId
            } else {
                showNotification('创建对话失败，无法发送消息');
                return;
            }
        } catch (e) {
            showNotification('创建对话失败，无法发送消息');
            return;
        }
    }
    const message = messageInput.value.trim();
    if (!message && !selectedFile) return;
    if (isStreaming) {
        stopStreaming();
        return;
    }
    // 先显示文件卡片（只要有文件）
    if (selectedFile) {
        addMessage('user', renderFileMessage(selectedFile), null, null, null, true);
        removeUploadedFile();
    }
    // 再显示消息文本（如果有消息）
    if (message) {
        let userMessage = message;
        if (selectedFile) {
            userMessage = `[上传文件: ${selectedFile.name}] ${message}`;
        }
        addMessage('user', userMessage);
        saveMessageToHistory('user', userMessage);
        messageInput.value = '';
        messageInput.style.height = 'auto';
    } else {
        messageInput.value = '';
        messageInput.style.height = 'auto';
    }
    // 发送后输入框回到底部，显示聊天区域，欢迎语隐藏
    const chatInputOuter = document.querySelector('.chat-input-outer');
    const chatArea = document.querySelector('.chat-area');
    const welcomeTip = document.getElementById('welcomeTip');
    if (chatInputOuter.classList.contains('floating-input-only')) {
        chatInputOuter.classList.remove('floating-input-only');
    }
    if (chatArea.classList.contains('hide-chat-messages')) {
        chatArea.classList.remove('hide-chat-messages');
    }
    if (welcomeTip) welcomeTip.style.display = 'none';
    // 只用样式控制按钮，不禁用
    sendBtn.classList.add('stop');
    sendBtn.innerHTML = '<i class="fas fa-stop"></i>';
    isStreaming = true;
    
    // 记录loading消息元素，用于后续立即移除
    let loadingMessageElement = null;
    
    try {
        // 组装参数
        let method = currentMode === 'full' ? 1 : 2;
        let fileId = uploadedFileId ? uploadedFileId : '1';
        const requestData = {
            conversationId: thisChatId,
            userInput: message,
            fileId: fileId,
            method: method
        };
        uploadedFileId = '1'; // 立刻重置，确保只用一次
        // 先渲染 loading 动画（确保在用户消息之后）
        if (!chatLoadingFlags[thisChatId]) {
            chatLoadingFlags[thisChatId] = true;
            saveLoadingFlagsToStorage();
            loadingMessageElement = addAssistantLoadingMessage(thisChatId);
        }
        const response = await fetch(`${API_BASE_URL}/v1/chat/generateTestCase`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(requestData)
        });
        const data = await response.json();
        
        // 立即移除loading动画，不等待其他异步操作
        if (loadingMessageElement && loadingMessageElement.parentNode) {
            // 先停止动画
            const typingIndicators = loadingMessageElement.querySelectorAll('.typing-indicator');
            typingIndicators.forEach(indicator => {
                indicator.classList.add('stop-animation');
            });
            // 短暂延迟后移除元素，确保动画停止效果可见
            setTimeout(() => {
                if (loadingMessageElement && loadingMessageElement.parentNode) {
                    loadingMessageElement.remove();
                }
            }, 100);
        }
        // 立即更新loading标志
        chatLoadingFlags[thisChatId] = false;
        saveLoadingFlagsToStorage();
        
        if (data.code === 10000 && data.data) {
            // 响应回来时校验对话ID，防止渲染到错误对话
            if (currentChatId !== thisChatId) {
                // 用户已切换对话，不渲染本次响应
                return;
            }
            Object.keys(data.data).forEach(key => {
                if (key !== 'code' && data.data[key]) {
                    if (key === 'testCases' && Array.isArray(data.data[key]) && data.data[key].length > 0) {
                        // 用表格显示 testCases
                        const testCasesContent = formatTestCases(data.data[key]);
                        addMessage('assistant', testCasesContent, null, new Date().toISOString(), data.data[key]);
                    } else if (
                        (typeof data.data[key] === 'string' || typeof data.data[key] === 'number') &&
                        String(data.data[key]) !== '成功生成全量测试用例' &&
                        String(data.data[key]) !== '成功生成测试用例'
                    ) {
                        // 只显示字符串和数字，且过滤掉特定内容
                        addMessage('assistant', String(data.data[key]), null, new Date().toISOString());
                    }
                    // 其它类型（如对象、布尔值）不显示
                }
            });
        }
        // 其它情况不显示任何assistant消息
    } catch (error) {
        console.error('发送消息失败:', error);
        // 错误时也要立即移除loading动画
        if (loadingMessageElement && loadingMessageElement.parentNode) {
            // 先停止动画
            const typingIndicators = loadingMessageElement.querySelectorAll('.typing-indicator');
            typingIndicators.forEach(indicator => {
                indicator.classList.add('stop-animation');
            });
            // 短暂延迟后移除元素，确保动画停止效果可见
            setTimeout(() => {
                if (loadingMessageElement && loadingMessageElement.parentNode) {
                    loadingMessageElement.remove();
                }
            }, 100);
        }
        chatLoadingFlags[thisChatId] = false;
        saveLoadingFlagsToStorage();
        addMessage('assistant', '抱歉，发生了错误，请稍后重试。');
    } finally {
        // 只用样式控制按钮，不禁用
        sendBtn.classList.remove('stop');
        sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i>';
        isStreaming = false;
        
        // 异步更新对话列表，不阻塞UI
        loadConversations().catch(error => {
            console.error('更新对话列表失败:', error);
        });
        
        // 新增：发送消息后拉取最新消息（仅在未切换对话时）
        if (currentChatId === thisChatId) {
            loadChatMessages(thisChatId).catch(error => {
                console.error('拉取消息失败:', error);
            });
        }
        
        messageInput.focus();
        messageInput.value = '';
    }
}

// 停止流式输出
function stopStreaming() {
    if (streamController) {
        streamController.abort();
    }
    isStreaming = false;
    // 只用样式控制按钮，不禁用
    sendBtn.classList.remove('stop');
    sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i>';
}

// 添加流式消息
function addStreamingMessage(type, content) {
    const messageDiv = document.createElement('div');
    messageDiv.className = `message ${type}`;
    
    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.textContent = type === 'user' ? 'U' : 'A';

    const messageContent = document.createElement('div');
    messageContent.className = 'message-content';

    const messageText = document.createElement('div');
    messageText.className = 'message-text';
    messageText.innerHTML = content + '<span class="typing-indicator"></span>';

    messageContent.appendChild(messageText);
    messageDiv.appendChild(avatar);
    messageDiv.appendChild(messageContent);

    chatMessages.appendChild(messageDiv);
    chatMessages.scrollTop = chatMessages.scrollHeight;
    
    return messageDiv;
}

// 更新流式消息
function updateStreamingMessage(messageDiv, content) {
    const messageText = messageDiv.querySelector('.message-text');
    messageText.innerHTML = content + '<span class="typing-indicator"></span>';
    chatMessages.scrollTop = chatMessages.scrollHeight;
}

// 完成流式消息
function completeStreamingMessage(messageDiv, content) {
    const messageText = messageDiv.querySelector('.message-text');
    // 检查内容是否包含HTML标签（如表格）
    if (content.includes('<table>') || content.includes('<div class="test-cases-container">')) {
        messageText.innerHTML = content;
    } else {
        messageText.textContent = content;
    }
}

// 新增：生成文件卡片HTML
function renderFileMessage(file) {
    const icon = '<i class="fas fa-file-alt" style="color:#FFD600;font-size:22px;margin-right:8px;"></i>';
    const fileSize = (file.size / 1024).toFixed(2) + 'KB';
    const url = URL.createObjectURL(file);
    return `
        <div class="file-message" style="display:flex;align-items:center;gap:10px;">
            ${icon}
            <a href="${url}" target="_blank" download="${file.name}" style="font-weight:600;color:#222;text-decoration:none;">${file.name}</a>
            <span style="color:#aaa;font-size:13px;">${fileSize}</span>
        </div>
    `;
}

// 添加消息到聊天窗口
function addMessage(type, content, msgId, time, testCases = null, isHtml = false) {
    const messageDiv = document.createElement('div');
    messageDiv.className = `message ${type}`;
    
    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.textContent = type === 'user' ? 'U' : 'A';

    const messageContent = document.createElement('div');
    messageContent.className = 'message-content';

    const messageText = document.createElement('div');
    messageText.className = 'message-text';
    
    // 检查内容是否包含HTML标签（如表格）
    if (isHtml) {
        messageText.innerHTML = content;
        // 如果是带表格的消息，给 messageContent 加特殊 class
        messageContent.classList.replace('message-content','with-table');
    } else if (content.includes('<table') || content.includes('<div class="test-cases-container">')) {
        messageText.innerHTML = content;
        // 如果是带表格的消息，给 messageContent 加特殊 class
        messageContent.classList.replace('message-content','with-table');
    } else {
        messageText.textContent = content;
    }

    messageContent.appendChild(messageText);
    messageDiv.appendChild(avatar);
    messageDiv.appendChild(messageContent);
    
    // 如果有测试用例数据，存储到消息元素中
    if (testCases && Array.isArray(testCases)) {
        messageDiv.dataset.testCases = JSON.stringify(testCases);
    }

    // 助手消息加编辑按钮和下载按钮（只有包含表格的消息才显示）
    if (type === 'assistant' && content.includes('<table class="test-cases-table">')) {
        const editBtn = document.createElement('button');
        editBtn.className = 'edit-btn';
        editBtn.innerHTML = '<i class="fas fa-edit"></i> 编辑';
        editBtn.onclick = function() {
            let tableData = parseTableData(content);
            let caseIdList = [];
            
           // 从当前消息元素中获取对应的测试用例数据
            const currentTestCases = messageDiv.dataset.testCases ? JSON.parse(messageDiv.dataset.testCases) : [];

            if (currentTestCases.length > 0) {
                tableData = tableData.map((row, idx) => {
                    const cid = currentTestCases[idx]?.case_id || '';
                    const sid = currentTestCases[idx]?.suite_id || '';
                    if (cid) caseIdList.push(cid);
                    if (sid) caseIdList.push(sid);
                    return {
                        ...row,
                        case_id: cid,
                        suite_id: sid,
                    };
                });
            } else {
                // 如果数据不匹配，尝试从表格数据中获取
                tableData.forEach(row => {
                    if (row.case_id) caseIdList.push(row.case_id);
                });
            }

            localStorage.setItem('editTableData', JSON.stringify(tableData));
            localStorage.setItem('editCaseIds', JSON.stringify(caseIdList));
            const suiteId = getCurrentSuiteId();
            window.location.href = `edit.html?msgId=${msgId || Date.now()}&chatId=${currentChatId || ''}&suiteId=${suiteId || ''}`;
        };
        messageContent.appendChild(editBtn);
        
        const downloadBtn = document.createElement('button');
        downloadBtn.className = 'download-btn';
        downloadBtn.innerHTML = '<i class="fas fa-download"></i> 下载';
        downloadBtn.onclick = function() {
            showDownloadDialog(content);
        };
        messageContent.appendChild(downloadBtn);
    }

    chatMessages.appendChild(messageDiv);
    chatMessages.scrollTop = chatMessages.scrollHeight;
}

// 新增文件上传到后端
async function uploadFileToServer(file) {
    const formData = new FormData();
    formData.append('message_id', '1');
    formData.append('file', file);
    try {
        const response = await fetch(`${API_BASE_URL}/v1/file/upload`, {
            method: 'POST',
            body: formData
        });
        const data = await response.json();
        if (data.code === 10000 && data.data && data.data.fileId) {
            return data.data.fileId;
        } else {
            return null;
        }
    } catch (e) {
        return null;
    }
}

// 处理文件上传
function handleFileUpload(event) {
    const file = event.target.files[0];
    if (!file) return;

    // 检查文件类型
    const allowedTypes = [
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    ];
    if (!allowedTypes.includes(file.type)) {
        alert('只支持 .doc 和 .docx 文件格式');
        return;
    }
    // 检查文件大小 (限制为 50MB)
    if (file.size > 50 * 1024 * 1024) {
        alert('文件大小不能超过 50MB');
        return;
    }
    setUploadLoading(true);
    // 真实上传
    uploadFileToServer(file).then(fileId => {
        setUploadLoading(false);
        if (fileId) {
            selectedFile = file;
            uploadedFileId = fileId;
            fileName.textContent = file.name;
            fileSize.textContent = `(${formatFileSize(file.size)})`;
            fileInfo.style.display = 'flex';
            showNotification(`文件 "${file.name}" 上传成功`);
        } else {
            selectedFile = file;
            uploadedFileId = '1';
            fileName.textContent = file.name;
            fileSize.textContent = `(${formatFileSize(file.size)})`;
            fileInfo.style.display = 'flex';
            showNotification('文件上传失败，将使用默认fileId=1');
        }
    });
}

// 设置上传动画
function setUploadLoading(loading) {
    const btn = uploadBtn;
    if (loading) {
        btn.classList.add('uploading');
    } else {
        btn.classList.remove('uploading');
    }
}

// 文件大小格式化
function formatFileSize(size) {
    if (size < 1024) return size + 'B';
    if (size < 1024 * 1024) return (size / 1024).toFixed(1) + 'KB';
    return (size / 1024 / 1024).toFixed(2) + 'MB';
}

// 移除上传的文件
function removeUploadedFile() {
    selectedFile = null;
    fileInfo.style.display = 'none';
    fileInput.value = '';
    fileSize.textContent = '';
}

// 切换模式
function switchMode(mode) {
    currentMode = mode;
    
    // 更新按钮状态
    modeButtons.forEach(btn => {
        btn.classList.remove('active');
        if (btn.dataset.mode === mode) {
            btn.classList.add('active');
        }
    });
    
    // 显示模式切换提示
    const modeText = mode === 'full' ? '全量测试' : '功能点测试';
    showNotification(`已切换到${modeText}模式`);
}

// 创建新对话
async function createNewChat() {
    try {
        // 1. 创建新对话并获取新对话ID
        const newChatId = await createConversation();
        // 2. 重新加载对话列表
        await loadConversations();
        // 3. 选中新建的对话
        if (newChatId) {
            selectChat(newChatId);
        }
        showNotification('新对话创建成功');
    } catch (error) {
        console.error('创建新对话失败:', error);
        showNotification('创建新对话失败');
    }
}

// 选择聊天
async function selectChat(chatId) {
    try {
        // 保存当前聊天记录
        if (currentChatId) {
            saveCurrentChat();
        }
        
        // 切换到新聊天
        currentChatId = chatId;
        localStorage.setItem('currentChatId', chatId);
        
        // 更新活跃状态
        document.querySelectorAll('.chat-item').forEach(item => {
            item.classList.remove('active');
            if (item.dataset.chatId === chatId) {
                item.classList.add('active');
            }
        });
        
        // 加载聊天消息
        await loadChatMessages(chatId);
        switchToChatMode();
        // 切换对话后，发送按钮状态根据 chatLoadingFlags 判断
        if (chatLoadingFlags[chatId]) {
            sendBtn.disabled = true;
            sendBtn.classList.add('stop');
            sendBtn.innerHTML = '<i class="fas fa-stop"></i>';
        } else {
            sendBtn.disabled = false;
            sendBtn.classList.remove('stop', 'disabled');
            sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i>';
        }
    } catch (error) {
        console.error('选择对话失败:', error);
        showNotification('选择对话失败');
    }
}

// 加载聊天消息
async function loadChatMessages(chatId) {
    if (currentChatId !== chatId) {
        // 用户已切换对话，不渲染
        return;
    }
    try {
        // 先移除现有的loading动画
        const existingLoadingMessages = chatMessages.querySelectorAll('.loading-message');
        existingLoadingMessages.forEach(msg => msg.remove());
        
        chatMessages.innerHTML = '';
        // 从后端获取消息
        const data = await getMessages(chatId);
        if (data && data.messageList && data.messageList.length > 0) {
            data.messageList.forEach(msg => {
                const messageType = msg.message_source === 0 ? 'user' : 'assistant';
                // 新增：如果有文件信息，渲染文件卡片
                if (msg.fileInfo) {
                    addMessage('user', renderFileCardFromInfo(msg.fileInfo), null, new Date().toISOString(), null, true);
                }
                // 渲染文本消息和测试用例
                if (msg.testCases && msg.testCases.length > 0) {
                    addMessage(messageType, msg.content, null, new Date().toISOString());
                    const testCasesContent = formatTestCases(msg.testCases);
                    addMessage('assistant', testCasesContent, null, new Date().toISOString(), msg.testCases);
                } else if (msg.content) {
                    addMessage(messageType, msg.content, null, new Date().toISOString());
                }
            });
            // 更新本地历史记录
            chatHistory[chatId] = {
                title: chatHistory[chatId]?.title || '对话',
                messages: data.messageList.map(msg => ({
                    type: msg.message_source === 0 ? 'user' : 'assistant',
                    content: msg.content,
                    timestamp: new Date().toISOString()
                }))
            };
        } else {
            if (!chatHistory[chatId]) {
                chatHistory[chatId] = {
                    title: '新对话',
                    messages: []
                };
            }
        }
        // 新增：如有 loading 动画标志则重新添加动画
        if (chatLoadingFlags[chatId]) {
            addAssistantLoadingMessage(chatId);
        }
        switchToChatMode();
        // 切换对话后，发送按钮状态根据 chatLoadingFlags 判断
        if (chatLoadingFlags[chatId]) {
            sendBtn.disabled = true;
            sendBtn.classList.add('stop');
            sendBtn.innerHTML = '<i class="fas fa-stop"></i>';
        } else {
            sendBtn.disabled = false;
            sendBtn.classList.remove('stop', 'disabled');
            sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i>';
        }
    }
    catch (error) {
        console.error('加载聊天消息失败:', error);
        showNotification('加载聊天消息失败');
    }
}

// 格式化测试用例显示
function formatTestCases(testCases) {
    if (!testCases || testCases.length === 0) {
        return '';
    }
    
    let tableHTML = `
        <div class="test-cases-container">
            <h3>生成的测试用例</h3>
            <div class="table-wrapper">
                <table class="test-cases-table">
                    <thead>
                        <tr>
                            <th>功能模块</th>
                            <th>用例编号</th>
                            <th>测试场景</th>
                            <th>前置条件</th>
                            <th>测试步骤</th>
                            <th>预期结果</th>
                        </tr>
                    </thead>
                    <tbody>
    `;
    
    testCases.forEach((testCase, index) => {
        tableHTML += `
            <tr>
                <td>${testCase.feature || '-'}</td>
                <td>${testCase.casenum || '-'}</td>
                <td>${testCase.scenario || '-'}</td>
                <td>${testCase.preconditions || '-'}</td>
                <td>${testCase.steps || '-'}</td>
                <td>${testCase.expected || '-'}</td>
            </tr>
        `;
    });
    
    tableHTML += `
                    </tbody>
                </table>
            </div>
        </div>
    `;
    
    return tableHTML;
}

// 保存消息到历史记录
function saveMessageToHistory(type, content) {
    if (!chatHistory[currentChatId]) {
        chatHistory[currentChatId] = {
            title: '新对话',
            messages: []
        };
    }
    
    chatHistory[currentChatId].messages.push({
        type: type,
        content: content,
        timestamp: new Date().toISOString()
    });
}

// 保存当前聊天
function saveCurrentChat() {
    // 这里可以添加保存到本地存储或后端的逻辑
    localStorage.setItem('chatHistory', JSON.stringify(chatHistory));
}

// 更新聊天列表
function updateChatList(chatId, title) {
    // 移除其他活跃状态
    document.querySelectorAll('.chat-item').forEach(item => {
        item.classList.remove('active');
    });
    
    // 检查是否已存在该对话
    const existingItem = document.querySelector(`[data-chat-id="${chatId}"]`);
    if (existingItem) {
        existingItem.classList.add('active');
        // 更新标题
        const titleSpan = existingItem.querySelector('.chat-title');
        if (titleSpan) {
            titleSpan.textContent = title;
        }
        return;
    }
    
    // 创建新的对话项
    const newChatItem = document.createElement('div');
    newChatItem.className = 'chat-item active';
    newChatItem.dataset.chatId = chatId;
    newChatItem.innerHTML = `
        <i class="fas fa-comment"></i>
        <span class="chat-title">${title}</span>
    `;
    
    // 添加到列表顶部
    chatList.insertBefore(newChatItem, chatList.firstChild);
    
    // 添加点击事件
    newChatItem.addEventListener('click', function() {
        selectChat(chatId);
    });
    
    // 如果列表超过10个，移除最旧的
    const chatItems = chatList.querySelectorAll('.chat-item');
    if (chatItems.length > 10) {
        chatList.removeChild(chatItems[chatItems.length - 1]);
    }
}


// 切换主题
function toggleTheme() {
    // 禁止切换深色主题，什么都不做
    return;
}

// 加载初始数据
function loadInitialData() {
    // 主题永远为浅色，不做任何切换
    // 加载侧边栏状态
    const savedSidebarState = localStorage.getItem('sidebarCollapsed');
    if (savedSidebarState === 'true') {
        toggleSidebar();
    }
    // 不再合并/覆盖chatHistory
}

// 显示通知
function showNotification(message) {
    const notification = document.createElement('div');
    notification.className = 'notification';
    notification.textContent = message;
    notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #64ffda;
        color: #0f0f23;
        padding: 12px 20px;
        border-radius: 6px;
        font-size: 14px;
        z-index: 1000;
        animation: slideIn 0.3s ease;
        box-shadow: 0 4px 12px rgba(0,0,0,0.15);
    `;
    
    document.body.appendChild(notification);
    
    setTimeout(() => {
        notification.style.animation = 'slideOut 0.3s ease';
        setTimeout(() => {
            if (document.body.contains(notification)) {
                document.body.removeChild(notification);
            }
        }, 300);
    }, 2000);
}

// 添加动画样式
const style = document.createElement('style');
style.textContent = `
    @keyframes slideIn {
        from {
            transform: translateX(100%);
            opacity: 0;
        }
        to {
            transform: translateX(0);
            opacity: 1;
        }
    }
    
    @keyframes slideOut {
        from {
            transform: translateX(0);
            opacity: 1;
        }
        to {
            transform: translateX(100%);
            opacity: 0;
        }
    }
`;
document.head.appendChild(style);

// 错误处理
window.addEventListener('error', function(e) {
    console.error('JavaScript 错误:', e.error);
    showNotification('发生错误，请刷新页面重试');
});

// 网络状态监听
window.addEventListener('online', function() {
    showNotification('网络连接已恢复');
});

window.addEventListener('offline', function() {
    showNotification('网络连接已断开');
});

// 页面卸载前保存数据
window.addEventListener('beforeunload', function() {
    saveCurrentChat();
}); 

// 解析表格数据
function parseTableData(tableContent) {
    const table = document.createElement('div');
    table.innerHTML = tableContent;
    const rows = table.querySelectorAll('.test-cases-table tbody tr');
    
    const data = [];
    rows.forEach(row => {
        const cells = row.querySelectorAll('td');
        data.push({
            feature: cells[0]?.textContent || '',
            casenum: cells[1]?.textContent || '',
            scenario: cells[2]?.textContent || '',
            preconditions: cells[3]?.textContent || '',
            steps: cells[4]?.textContent || '',
            expected: cells[5]?.textContent || '',
        });
    });
    
    return data;
}

// 下载功能
// 显示下载对话框
function showDownloadDialog(tableContent) {
    // 创建模态对话框
    const modal = document.createElement('div');
    modal.className = 'download-modal';
    modal.innerHTML = `
        <div class="download-modal-content">
            <div class="download-modal-header">
                <h3>选择下载格式</h3>
                <button class="close-btn" onclick="this.closest('.download-modal').remove()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="download-modal-body">
                <div class="download-options">
                    <button class="download-option" data-format="csv">
                        <i class="fas fa-file-csv"></i>
                        <span>CSV 文件</span>
                    </button>
                    <button class="download-option" data-format="excel">
                        <i class="fas fa-file-excel"></i>
                        <span>Excel 文件</span>
                    </button>
                    <button class="download-option" data-format="word">
                        <i class="fas fa-file-word"></i>
                        <span>Word 文档</span>
                    </button>
                    <button class="download-option" data-format="markdown">
                        <i class="fas fa-file-alt"></i>
                        <span>Markdown 文档</span>
                    </button>
                </div>
            </div>
        </div>
    `;
    
    // 添加点击事件
    modal.addEventListener('click', function(e) {
        if (e.target.classList.contains('download-option')) {
            const format = e.target.dataset.format;
            downloadTable(tableContent, format);
            modal.remove();
        }
    });
    
    // 添加到页面
    document.body.appendChild(modal);
}

// 下载表格数据
function downloadTable(tableContent, format) {
    // 使用统一的解析函数
    const data = parseTableData(tableContent);
    
    // 根据格式下载
    switch (format) {
        case 'csv':
            downloadCSV(data);
            break;
        case 'excel':
            downloadExcel(data);
            break;
        case 'word':
            downloadWord(data);
            break;
        case 'markdown':
            downloadMarkdown(data);
            break;
    }
}

// 下载CSV文件
function downloadCSV(data) {
    const headers = ['功能模块', '用例编号', '测试场景', '前置条件', '测试步骤', '预期结果'];
    const csvContent = [
        headers.join(','),
        ...data.map(row => [
            `"${row.feature}"`,
            `"${row.casenum}"`,
            `"${row.scenario}"`,
            `"${row.preconditions}"`,
            `"${row.steps}"`,
            `"${row.expected}"`
        ].join(','))
    ].join('\n');
    
    const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `测试用例_${new Date().toISOString().slice(0, 10)}.csv`;
    link.click();
    showNotification('CSV文件下载成功');
}

// 下载Excel文件
function downloadExcel(data) {
    try {
        // 检查SheetJS库是否可用
        if (typeof XLSX === 'undefined') {
            showNotification('Excel下载功能需要额外库支持，请刷新页面重试');
            return;
        }
        
        const headers = ['功能模块', '用例编号', '测试场景', '前置条件', '测试步骤', '预期结果'];
        const excelData = [headers, ...data.map(row => [
            row.feature, row.casenum, row.scenario, row.preconditions, row.steps, row.expected
        ])];
        
        const ws = XLSX.utils.aoa_to_sheet(excelData);
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, '测试用例');
        
        XLSX.writeFile(wb, `测试用例_${new Date().toISOString().slice(0, 10)}.xlsx`);
        showNotification('Excel文件下载成功');
    } catch (error) {
        console.error('Excel下载失败:', error);
        showNotification('Excel下载失败，请尝试其他格式');
    }
}

// 移除 downloadPDF 函数，添加 downloadWord 函数
function downloadWord(data) {
    // 1. 构建 Word 文档内容（HTML）
    const headers = ['功能模块', '用例编号', '测试场景', '前置条件', '测试步骤', '预期结果'];
    let html = '<html><head><meta charset="utf-8"></head><body>';
    html += `<h2>测试用例导出</h2>`;
    html += '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse:collapse;">';
    html += '<tr>' + headers.map(h => `<th>${h}</th>`).join('') + '</tr>';
    data.forEach(row => {
        html += '<tr>' + [row.feature, row.casenum, row.scenario, row.preconditions, row.steps, row.expected].map(cell => `<td>${cell || ''}</td>`).join('') + '</tr>';
    });
    html += '</table></body></html>';
    // 2. 生成 Blob 并下载
    const blob = new Blob(['\ufeff' + html], { type: 'application/msword' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `测试用例_${new Date().toISOString().slice(0, 10)}.doc`;
    link.click();
    showNotification('Word文档下载成功');
}

// 下载Markdown文件
function downloadMarkdown(data) {
    let markdown = '# 测试用例报告\n\n';
    markdown += `生成时间: ${new Date().toLocaleString()}\n\n`;
    
    data.forEach((row, index) => {
        markdown += `## 测试用例 ${index + 1}\n\n`;
        markdown += `| 字段 | 内容 |\n`;
        markdown += `|------|------|\n`;
        markdown += `| 功能模块 | ${row.feature} |\n`;
        markdown += `| 用例编号 | ${row.casenum} |\n`;
        markdown += `| 测试场景 | ${row.scenario} |\n`;
        markdown += `| 前置条件 | ${row.preconditions} |\n`;
        markdown += `| 测试步骤 | ${row.steps} |\n`;
        markdown += `| 预期结果 | ${row.expected} |\n\n`;
    });
    
    const blob = new Blob([markdown], { type: 'text/markdown;charset=utf-8;' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = `测试用例_${new Date().toISOString().slice(0, 10)}.md`;
    link.click();
    showNotification('Markdown文件下载成功');
}


// 获取当前suiteId
function getCurrentSuiteId() {
    // 从当前对话的消息中查找包含测试用例的消息，获取suiteId
    if (currentChatId && chatHistory[currentChatId]) {
        const messages = chatHistory[currentChatId].messages;
        for (let i = messages.length - 1; i >= 0; i--) {
            const message = messages[i];
            if (message.type === 'assistant' && message.content.includes('<table class="test-cases-table">')) {
                // 这里可以从消息中提取suiteId，或者从后端API获取
                // 暂时返回一个默认值，实际项目中应该从消息或API中获取
                return message.suiteId || 'default-suite';
            }
        }
    }
    return '';
}

// 切换到正常聊天界面
function switchToChatMode() {
    const chatInputOuter = document.querySelector('.chat-input-outer');
    const chatArea = document.querySelector('.chat-area');
    const welcomeTip = document.getElementById('welcomeTip');
    if (chatInputOuter && chatInputOuter.classList.contains('floating-input-only')) {
        chatInputOuter.classList.remove('floating-input-only');
    }
    if (chatArea && chatArea.classList.contains('hide-chat-messages')) {
        chatArea.classList.remove('hide-chat-messages');
    }
    if (welcomeTip) welcomeTip.style.display = 'none';
}

// 新增 assistant 消息生成中时的三点闪烁 loading 占位，绑定 chatId
function addAssistantLoadingMessage(chatId) {
    const messageDiv = document.createElement('div');
    messageDiv.className = 'message assistant loading-message';
    const avatar = document.createElement('div');
    avatar.className = 'message-avatar';
    avatar.textContent = 'A';
    const messageContent = document.createElement('div');
    messageContent.className = 'message-content';
    const messageText = document.createElement('div');
    messageText.className = 'message-text loading-dots'; // 只在 loading 时加 loading-dots
    messageText.innerHTML = `
        <span class="typing-indicator"></span>
        <span class="typing-indicator"></span>
        <span class="typing-indicator"></span>
    `;
    messageContent.appendChild(messageText);
    messageDiv.appendChild(avatar);
    messageDiv.appendChild(messageContent);
    // 绑定 chatId
    messageDiv.dataset.chatId = chatId;
    chatMessages.appendChild(messageDiv);
    chatMessages.scrollTop = chatMessages.scrollHeight;
    return messageDiv;
}

// 新增：渲染所有本地持久化文件卡片
// function renderAllFileCards() {
//     let fileCards = JSON.parse(localStorage.getItem('fileCards') || '[]');
//     fileCards.forEach(card => {
//         addMessage('user', renderFileCardFromInfo(card), null, null, null, true);
//     });
// } // 删除 renderAllFileCards 及其调用
// 新增：渲染文件卡片
function renderFileCardFromInfo(info) {
    const icon = '<i class="fas fa-file-alt" style="color:#FFD600;font-size:22px;margin-right:8px;"></i>';
    return `
        <div class="file-message" style="display:flex;align-items:center;gap:10px;">
            ${icon}
            <span style="font-weight:600;color:#222;">${info.file_name || '未知文件'}</span>
            <span style="color:#aaa;font-size:13px;">${info.file_size || ''}</span>
        </div>
    `;
}